﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;


namespace Mewdam.OAuth
{
    public class OAuthParameter
    {
        bool isParamentersSorted;

        private Dictionary<ParameterType, string> parameters = new Dictionary<ParameterType, string>();
        public Dictionary<ParameterType, string> Parameters
        {
            get 
            {
                if (!isParamentersSorted)
                {
                    //调试成功后将p.key.tostring 改成P.key enum里修改顺序
                    var sortedParaments = from p in parameters where p.Value != null orderby p.Key.ToString() select p;
                    parameters = new Dictionary<ParameterType, string>();
                    foreach (var p in sortedParaments)
                    {
                        parameters.Add(p.Key, p.Value);
                    }
                    isParamentersSorted = true;
                }
                return parameters; 
            }
        }

        public enum ParameterType
        {
            oauth_callback,
            oauth_consumer_key,
            oauth_nonce,
            oauth_signature,
            oauth_signature_method,
            oauth_timestamp,
            oauth_token,
            oauth_verifier,
            oauth_version,
            //home_timeline optional
            since_id,
            max_id,
            count,
            page,
            trim_user,
            include_entities
        }

        /// <summary>
        /// structor base
        /// </summary>
        /// <param name="consumerKey"></param>
        public OAuthParameter(string consumerKey ) 
        {
            AddParameter(ParameterType.oauth_consumer_key, consumerKey);
            AddParameter(ParameterType.oauth_nonce, GenerateNonce());
            ////AddParameter(ParameterType.oauth_nonce, "98e423176133efda1536fef0909f56e6");
            AddParameter(ParameterType.oauth_timestamp, GenerateTimeStamp());
            ////AddParameter(ParameterType.oauth_timestamp, "1289291562");
            AddParameter(ParameterType.oauth_signature_method, "HMAC-SHA1");
            AddParameter(ParameterType.oauth_version, "1.0");
        }

        /// <summary>
        /// Use this if u have access token
        /// </summary>
        /// <param name="consumerKey"></param>
        /// <param name="consumerSecret"></param>
        /// <param name="token"></param>
        /// <param name="tokenSecret"></param>
        public OAuthParameter(string consumerKey,string token) 
            :this(consumerKey)
        {
            AddParameter(ParameterType.oauth_token, token);
        }

        /// <summary>
        /// Use this to request token
        /// </summary>
        /// <param name="consumerKey"></param>
        /// <param name="dummy">no use</param>
        /// <param name="callback"></param>
        public OAuthParameter(string consumerKey,string callback,int dummy)
            : this(consumerKey)
        {
            AddParameter(ParameterType.oauth_callback, callback);

        }

        /// <summary>
        /// getting token
        /// </summary>
        /// <param name="consumerKey"></param>
        /// <param name="token"></param>
        /// <param name="verifier"></param>
        public OAuthParameter(string consumerKey, string token, string verifier) 
            :this(consumerKey)
        {
            AddParameter(ParameterType.oauth_token, token);
            AddParameter(ParameterType.oauth_verifier, verifier);
        }

        public void AddParameter(ParameterType parameterType, string value)
        {
            if (parameters.ContainsKey(parameterType))
            {
                parameters[parameterType] = value;
            }
            else
            {
                parameters.Add(parameterType, value);

            }
        }


    #region Utilities

        /// <summary>
        /// Generate the timestamp for the signature        
        /// </summary>
        /// <returns></returns>
        private string GenerateTimeStamp()
        {
            // Default implementation of UNIX time of the current UTC time
            TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return Convert.ToInt64(ts.TotalSeconds).ToString();
        }

        /// <summary>
        /// Generate a nonce
        /// </summary>
        /// <returns></returns>
        private string GenerateNonce()
        {
            // Just a simple implementation of a random number between 123400 and 9999999
            return new Random().Next(123400, 9999999).ToString();

        }
    #endregion


    }
}